package wsi.exp;

import java.io.File;
import java.io.FileFilter;
import java.util.Arrays;

import wsi.script.AppConfig;

public class ExpFolderController {
	public final static String EXP = "exp";

	private final static ExpFolderController shared = new ExpFolderController();

	public static ExpFolderController shared() {
		return shared;
	}

	private final File resultFolder = AppConfig.shared().getExperimentsFolder();

	/**
	 * <ul>
	 * <li>exp 0: for temp tasks.</li>
	 * <li>exp 1: selected subtrees, identify isomorphic subtree root</li>
	 * <li>exp 2: tree to entity match (exists, forall)</li>
	 * <li>exp 3: xpath to predicate path match (pair, pred)</li>
	 * <li>exp 4: input selection (rnd, deg_s, feedback)</li>
	 * <li>exp 5: tree to entity instance match (exp2b)</li>
	 * <li>exp 6: functional dependency</li>
	 * </ul>
	 */
	private ExpFolderController() {
		for (int i = 0; i < 7; i++) {
			File dir = getFolderForExp(i);

			if (!dir.exists())
				dir.mkdir();
		}
	}

	private File getClean(File dir) {
		return mkdir(dir, "clean");
	}

	private File getDebug(File dir) {
		return mkdir(dir, "debug");
	}

	private File getFile(File[] files) {
		assert files.length == 1 : Arrays.toString(files);
		return files[0];
	}

	private File getFolderForExp(final int index) {
		return new File(resultFolder, EXP + index);
	}

	public File getFolderForExp0() {
		return getFolderForExp(0);
	}

	public File getFolderForExp1() {
		return getFolderForExp(1);
	}

	public File getFolderForExp2() {
		return getFolderForExp(2);
	}

	public File getFolderForExp2Debug() {
		return getDebug(getFolderForExp(2));
	}

	public File getFolderForExp3() {
		return getFolderForExp(3);
	}

	public File getFolderForExp3Debug() {
		return getDebug(getFolderForExp(3));
	}

	public File getFolderForExp3DebugClean() {
		return getClean(getDebug(getFolderForExp(3)));
	}

	public File getFolderForExp3DebugCleanDebug() {
		return getDebug(getClean(getDebug(getFolderForExp(3))));
	}

	public File getFolderForExp4() {
		return getFolderForExp(4);
	}

	public File getFolderForExp5() {
		return getFolderForExp(5);
	}

	public File getFolderForExp6() {
		return getFolderForExp(6);
	}

	private File getGoldFolderForExp(final int index) {
		return getGoldFolderForExp(AppConfig.shared().getKnowledgeDatabase(),
				index);
	}

	private File getGoldFolderForExp(String kdb, final int index) {
		File dir = AppConfig.shared().getGoldSetFolder(kdb);

		return getFile(dir.listFiles(new FileFilter() {

			@Override
			public boolean accept(File file) {
				if (!file.isDirectory())
					return false;

				String name = file.getName();
				return name.contains(EXP + index);
			}
		}));
	}

	public File getGoldFolderForExp1() {
		return getGoldFolderForExp(1);
	}

	public File getGoldFolderForExp1(String kdb) {
		return getGoldFolderForExp(kdb, 1);
	}

	public File getGoldFolderForExp2() {
		return getGoldFolderForExp(2);
	}

	public File getGoldFolderForExp2(String kdb) {
		return getGoldFolderForExp(kdb, 2);
	}

	public File getGoldFolderForExp2Debug() {
		return getDebug(getGoldFolderForExp(2));
	}

	public File getGoldFolderForExp3() {
		return getGoldFolderForExp(3);
	}

	public File getGoldFolderForExp5() {
		return getGoldFolderForExp(5);
	}

	public File getGoldFolderForExp6() {
		return getGoldFolderForExp(6);
	}

	public File getResultFolder() {
		return resultFolder;
	}

	private File mkdir(File dir, String subdir) {
		File folder = new File(dir, subdir);

		if (!folder.exists())
			folder.mkdir();

		return folder;
	}
}
